#include "Timer.hpp"

uint64_t Timer::gid = 0;

Timer::Timer(EventLoop* loop): loop_(loop) {
    timerfd_ = timerfd_create(CLOCK_MONOTONIC, 0);
    if (timerfd_ == -1)
    {
        perror("timerfd_create");
    }

    struct itimerspec new_value = {};
    new_value.it_value.tv_sec  = 1000; // 很大的时间
    new_value.it_value.tv_nsec = 0;
    
    new_value.it_interval.tv_sec  = 0; // one shot
    new_value.it_interval.tv_nsec = 0;

    if (timerfd_settime(timerfd_, 0, &new_value, NULL) == -1)
    {
        perror("timerfd_settime");
    }
    auto ptr = std::make_shared<std::function<void()>>(std::bind(&Timer::consumeTimeEvent, this));
    loop_->addNormalEvent(timerfd_, EPOLLIN | EPOLLET, ptr);
}

void Timer::consumeTimeEvent(){
    auto it = timeouts_.begin();
    while (it != timeouts_.end() && it->expire <= getTick()) {
        (*it->func)();
        if (it->cycle) { // 循环任务
            timeouts_.emplace(it->expire+it->cycle, genId(), it->func, it->cycle);
        }
        it = timeouts_.erase(it);
    }

    it = timeouts_.begin();
    if (it != timeouts_.end()) {
        time_t time = it->expire - getTick(); // ms
        struct itimerspec new_value = {};
        new_value.it_value.tv_sec  = time / 1000;  // s
        new_value.it_value.tv_nsec = time % 1000 * 1000000;  // ns
        
        new_value.it_interval.tv_sec  = 0; // one shot
        new_value.it_interval.tv_nsec = 0;
        if (timerfd_settime(timerfd_, 0, &new_value, NULL) == -1)
        {
            perror("timerfd_settime");
        }
    }

}

bool operator<(const TimerNode& l, const TimerNode& r){
    if (l.expire < r.expire) {
        return true;
    }
    else if (l.expire > r.expire) {
        return false;
    }
    else {
        return l.id < r.id;
    }
}